home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-02 / tool-inc.zip / POPUP.INC < prev    next >
Text File  |  1989-03-01  |  9KB  |  396 lines

  1.  
  2. (*
  3.  * Copyright 1987, 1989 Samuel H. Smith;  All rights reserved
  4.  *
  5.  * This is a component of the ProDoor System.
  6.  * Do not distribute modified versions without my permission.
  7.  * Do not remove or alter this notice or any other copyright notice.
  8.  * If you use this in your own program you must distribute source code.
  9.  * Do not use any of this in a commercial product.
  10.  *
  11.  *)
  12.  
  13. (*
  14.  * popup - utility library for simple "pop-up" windows (3-1-89)
  15.  *
  16.  *)
  17.  
  18. const
  19.    low_attr:  integer = 7;
  20.    norm_attr: integer = 15;
  21.    back_attr: integer = 0;
  22.  
  23.    slowdisplay:      boolean = false;
  24.    default_disp_seg: integer = $B800;
  25.  
  26. type
  27.    popup_string = string[255];
  28.  
  29.    screenloc =         record
  30.          character:          char;
  31.          attribute:          byte;
  32.    end;
  33.  
  34.    videoram =          array [0..1999] of screenloc;
  35.    videoptr =          ^videoram;
  36.  
  37.    window_rec = record
  38.       x1,y1,x2,y2: integer;
  39.       attr:        byte;
  40.    end;
  41.  
  42.    window_save_rec = record
  43.       win:      window_rec;
  44.       scr:      videoram;
  45.       cux,cuy:  integer;
  46.    end;
  47.  
  48.  
  49. var
  50.    cur_window:   window_rec;
  51.    saved_window: window_save_rec;
  52.    disp_mem:     videoptr;
  53.    disp_seg:     integer;
  54.  
  55.  
  56. procedure determine_video_ptr;     {determine video display area when
  57.                                     running under DESQview - also works
  58.                                     without DESQview}
  59. const
  60.    video_ptr_known: boolean = false;
  61. begin
  62.  
  63. {   if video_ptr_known then exit; }
  64.  
  65.    disp_seg := default_disp_seg;
  66.  
  67.    inline( $55/                    {push bp}
  68.            $a1/disp_seg/           {mov ax,[disp_seg]}
  69.            $8e/$c0/                {mov es,ax}
  70.            $bf/$00/$00/            {mov di,0}
  71.            $b4/$fe/                {mov ah,fe}
  72.            $cd/$10/                {int 10h}
  73.            $5d/                    {pop bp}
  74.            $8c/$06/disp_seg);      {mov [disp_seg],es}
  75.  
  76.    disp_mem := ptr(disp_seg,0);
  77.    video_ptr_known := true;
  78. end;
  79.  
  80.  
  81. procedure normvideo;
  82. begin
  83.    textcolor(norm_attr);
  84.    textbackground(back_attr);
  85.    cur_window.attr := norm_attr + back_attr shl 4;
  86. end;
  87.  
  88.  
  89. procedure lowvideo;
  90. begin
  91.    textcolor(low_attr);
  92.    textbackground(back_attr);
  93.    cur_window.attr := low_attr + back_attr shl 4;
  94. end;
  95.  
  96.  
  97.  
  98. procedure old_window(win: window_rec);   {redefine the old window
  99.                                           command so it can still be
  100.                                           used by other procs}
  101. begin
  102.    with win do
  103.       window(x1,y1,x2,y2);
  104. end;
  105.  
  106.  
  107.  
  108. procedure window(a1,b1,a2,b2: integer);    {make a new version of window
  109.                                             that saves the current state}
  110. begin
  111.    determine_video_ptr;
  112.  
  113.    with cur_window do
  114.    begin
  115.       x1 := a1;
  116.       y1 := b1;
  117.       x2 := a2;
  118.       y2 := b2;
  119.    end;
  120.  
  121.    old_window(cur_window);
  122. end;
  123.  
  124.  
  125.  
  126. function make_string(c: char; len: integer): popup_string;
  127.                                    {make a string by repeating
  128.                                     a character n times}
  129. var
  130.    i:  integer;
  131.    s:  popup_string;
  132. begin
  133.    for i := 1 to len do
  134.       s[i] := c;
  135.  
  136.    s[0] := chr(len);
  137.    make_string := s;
  138. end;
  139.  
  140.  
  141.  
  142. function invisible: boolean;   {is this the invisible program under doubledos?}
  143. var
  144.    reg:  registers;
  145.  
  146. begin
  147.    determine_video_ptr;
  148.  
  149.    reg.ax := $e400;   {doubledos return program status}
  150.    msdos(reg);
  151.  
  152.    if (lo(reg.ax) = 2) or slowdisplay then
  153.       invisible := true
  154.    else
  155.       invisible := false;
  156. end;
  157.  
  158.  
  159.  
  160. procedure disp (s:                  popup_string);
  161.                                      {very fast dma string display}
  162. var
  163.    index:              integer;
  164.    i:                  integer;
  165.    c:                  char;
  166.    len:                integer;
  167.    max_index:          integer;
  168.  
  169. begin
  170.  
  171.  
  172.    if invisible or (length(s) < 4) then
  173.                      {can't do dma screens if invisble under doubledos.
  174.                       this is slower than write for short strings}
  175.    begin
  176.       write(s);
  177.       exit;
  178.    end;
  179.  
  180.  
  181.    with cur_window do
  182.    begin
  183.       len := length (s);
  184.       index :=(wherey + y1 - 2)* 80 +(wherex + x1 - 2);
  185.       max_index := y2*80;
  186.  
  187.       for i := 1 to len do
  188.       begin
  189.          c := s [i];
  190.  
  191.          case c of
  192.             ^H:   index := index - 1;
  193.  
  194.             ^J:   begin
  195.                      index := index + 80;
  196.                      if index >= max_index then
  197.                      begin
  198.                         write(^J);
  199.                         index := index - 80;
  200.                      end;
  201.                   end;
  202.  
  203.             ^M:   index :=(index div 80)* 80 + x1 - 1;
  204.  
  205.             ^G:   write(^G);
  206.  
  207.             else  begin
  208.                      with disp_mem^[index] do
  209.                      begin
  210.                         character := c;
  211.                         attribute := attr;
  212.                      end;
  213.  
  214.                      index := index + 1;
  215.  
  216.                      if index >= max_index then
  217.                      begin
  218.                         index := index - 80;
  219.                         writeln;
  220.                      end;
  221.                   end;
  222.          end;
  223.       end;
  224.  
  225.  
  226. (* place cursor at end of displayed string *)
  227.  
  228.       gotoxy((index mod 80)- x1 + 2,(index div 80)- y1 + 2);
  229.    end;
  230. end;
  231.  
  232.  
  233.  
  234. procedure displn(s: popup_string);       {fast display and linefeed}
  235. begin
  236.    disp(s);
  237.    writeln;
  238. end;
  239.  
  240.  
  241.  
  242. procedure open_pop_up(x1,y1,x2,y2: integer; title: popup_string);
  243.                                             {open a titled pop up window
  244.                                              and save previous screen
  245.                                              state so it can be restored}
  246. const
  247.    topleft =           #213;
  248.    topright =          #184;
  249.    botleft =           #212;
  250.    botright =          #190;
  251.    sides =             #179;
  252.    tops =              #205;
  253.  
  254. var
  255.    i,
  256.    j:                  integer;
  257.    side:               popup_string;
  258.    top:                popup_string;
  259.    bottom:             popup_string;
  260.  
  261. begin
  262.  
  263. (* save the current window so it can be restored later *)
  264.    determine_video_ptr;
  265.    saved_window.scr := disp_mem^;
  266.    saved_window.win := cur_window;
  267.    saved_window.cux := wherex;
  268.    saved_window.cuy := wherey;
  269.    window(1,1,80,25);
  270.  
  271.  
  272. (* create window section strings *)
  273.    if title <> '' then
  274.       title := ' ' + title + ' ';
  275.                               {leave spaces around the title, if any}
  276.  
  277.  
  278. (* top of frame *)
  279.    top := make_string (tops, x2 - length (title)- x1 - 2) + topright;
  280.  
  281.  
  282. (* sides of frame *)
  283.    side := '';
  284.    j := 1;
  285.  
  286.    for i :=(y1 + 1) to (y2 - 1) do
  287.    begin
  288.       side[j]:= sides;
  289.       side[j + 1]:=^H;
  290.       side[j + 2]:=^J;
  291.       j := j + 3;
  292.    end;
  293.  
  294.    side[0]:= chr (j - 1);
  295.  
  296.  
  297. (* bottom of frame *)
  298.    bottom := botleft + make_string (tops, x2 - x1 - 1)+ botright;
  299.  
  300.  
  301. (* draw the frame *)
  302.    gotoxy(x1, y1);
  303.    disp(topleft + tops + title + top);
  304.  
  305.    gotoxy(x1, y1 + 1);
  306.    disp(side);
  307.  
  308.    gotoxy(x2, y1 + 1);
  309.    disp(side);
  310.  
  311.    gotoxy(x1, y2);
  312.    disp(bottom);
  313.  
  314. (* define the new window.  let the caller decide if it needs clearing *)
  315.    window(x1+1,y1+1,x2-1,y2-1);
  316.  
  317. end;
  318.  
  319.  
  320.  
  321. procedure remove_pop_up;        {restore the screen like it was
  322.                                  before the popup window was opened}
  323. begin
  324.  
  325. (* restore the windowing settings *)
  326.    cur_window := saved_window.win;
  327.    old_window(cur_window);
  328.  
  329. (* restore the cursor position *)
  330.    gotoxy(saved_window.cux,saved_window.cuy);
  331.  
  332. (* restore the display contents *)
  333.    disp_mem^ := saved_window.scr;
  334.  
  335. (* restore current video mode *)
  336.    if cur_window.attr = low_attr then
  337.       lowvideo
  338.    else
  339.       normvideo;
  340. end;
  341.  
  342.  
  343. procedure preserve_screen(name: popup_string);
  344.                                 {preserve contents in a named file}
  345. var
  346.    fd:  file of window_save_rec;
  347.  
  348. begin
  349.    if invisible then
  350.       exit;
  351.  
  352.    assign(fd,name);
  353. {$I-}
  354.    rewrite(fd);
  355. {$I+}
  356.    if ioresult = 0 then
  357.    begin
  358.       open_pop_up(1,1,5,5,'');
  359.       remove_pop_up;
  360.       write(fd,saved_window);
  361.       close(fd);
  362.    end;
  363. end;
  364.  
  365.  
  366. procedure restore_screen(name: popup_string);
  367.                                {restore a preserved screen from a file;
  368.                                 don't touch screen if file is missing}
  369. var
  370.    fd:  file of window_save_rec;
  371.  
  372. begin
  373.    if invisible then
  374.       exit;
  375.  
  376.    assign(fd,name);
  377. {$I-}
  378.    reset(fd);
  379. {$I+}
  380.    if ioresult = 0 then
  381.    begin
  382.       read(fd,saved_window);
  383.       close(fd);
  384.       remove_pop_up;
  385.    end;
  386.  
  387. end;
  388.  
  389.  
  390. procedure init_pop_up;   {call once before anything else in this library}
  391. begin
  392.    window(1,1,80,25);
  393.    normvideo;
  394. end;
  395.  
  396.